home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue41 / Patterns / HVTimeKeeper.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-11-18  |  3.7 KB  |  155 lines

  1. unit HVTimeKeeper;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils;
  7.  
  8. type
  9.   ESingleton = class(Exception);
  10.  
  11.   TInvalidateDestroy = class(TObject)
  12.   protected
  13.     class procedure SingletonError;
  14.   public
  15.     destructor Destroy; override;
  16.   end;
  17.  
  18.   TTimeKeeper = class;
  19.   TTimeKeeperClass = class of TTimeKeeper;
  20.   TTimeKeeper = class(TInvalidateDestroy)
  21.   private
  22.     class procedure Shutdown;
  23.     function GetTime: TDateTime;
  24.     function GetDate: TDateTime;
  25.     function GetNow: TDateTime;
  26.   protected
  27.     // Allow descendents to set a new class for the instance:
  28.     class procedure SetTimeKeeperClass(aTimeKeeperClass: TTimeKeeperClass);
  29.     // Actual constructor and destructor that will be used:
  30.     constructor SingletonCreate; virtual;
  31.     destructor SingletonDestroy; virtual;
  32.   public
  33.     // Not for use - for obstruction only:
  34.     class procedure Create;
  35.     class procedure Free(Dummy: integer);
  36. {$IFNDEF VER120} {$WARNINGS OFF} {$ENDIF}
  37.     // This generates a warning in D3. D4 has the reintroduce keyword to solve this
  38.     class procedure Destroy(Dummy: integer); {$IFDEF VER120} reintroduce; {$ENDIF}
  39.     // Simple interface:
  40.     class function Instance: TTimeKeeper;
  41.     property Time: TDateTime read GetTime;
  42.     property Date: TDateTime read GetDate;
  43.     property Now: TDateTime read GetNow;
  44.   end;
  45. {$IFNDEF VER120} {$WARNINGS ON} {$ENDIF}
  46.  
  47. function TimeKeeper: TTimeKeeper;
  48.  
  49. implementation
  50.  
  51. class procedure TInvalidateDestroy.SingletonError;
  52. // Raise an exception in case of illegal use
  53. begin
  54.   raise ESingleton.CreateFmt('Illegal use of %s singleton instance!', [ClassName]);
  55. end;
  56.  
  57. destructor TInvalidateDestroy.Destroy;
  58. // Protected against use of default destructor
  59. begin
  60.   SingletonError;
  61. end;
  62.  
  63. { TTimeKeeper }
  64.  
  65. var
  66.   TimeKeeperInstance: TTimeKeeper = nil;
  67.   TimeKeeperClass: TTimeKeeperClass = TTimeKeeper;
  68.  
  69. class procedure TTimeKeeper.SetTimeKeeperClass(aTimeKeeperClass: TTimeKeeperClass);
  70. // Allow change of instance class
  71. begin
  72.   Assert(Assigned(aTimeKeeperClass));
  73.   if Assigned(TimeKeeperInstance) then
  74.     SingletonError;
  75.   TimeKeeperClass := aTimeKeeperClass;
  76. end;
  77.  
  78. class function TTimeKeeper.Instance: TTimeKeeper;
  79. // Single Instance function - create when first needed
  80. begin
  81.   Assert(Assigned(TimeKeeperClass));
  82.   if not Assigned(TimeKeeperInstance) then
  83.     TimeKeeperInstance := TimeKeeperClass.SingletonCreate;
  84.   Result := TimeKeeperInstance;
  85. end;
  86.  
  87. class procedure TTimeKeeper.Shutdown;
  88. // Time to close down the show
  89. begin
  90.   if Assigned(TimeKeeperInstance) then
  91.   begin
  92.     TimeKeeperInstance.SingletonDestroy;
  93.     TimeKeeperInstance := nil;
  94.   end;
  95. end;
  96.  
  97. constructor TTimeKeeper.SingletonCreate;
  98. // Protected constructor
  99. begin
  100.   inherited Create;
  101. end;
  102.  
  103. destructor TTimeKeeper.SingletonDestroy;
  104. // Protected destructor
  105. begin
  106.   // We cannot call inherited Destroy; here!
  107.   // It would raise an ESingleton exception
  108. end;
  109.  
  110. // Protected against use of default constructor
  111. class procedure TTimeKeeper.Create;
  112. begin
  113.   SingletonError;
  114. end;
  115.  
  116. // Protected against use of Free
  117. class procedure TTimeKeeper.Free(Dummy: integer);
  118. begin
  119.   SingletonError;
  120. end;
  121.  
  122. class procedure TTimeKeeper.Destroy(Dummy: integer);
  123. begin
  124.   SingletonError;
  125. end;
  126.  
  127. // Property access methods
  128. function TTimeKeeper.GetDate: TDateTime;
  129. begin
  130.   Result := SysUtils.Date;
  131. end;
  132.  
  133. function TTimeKeeper.GetNow: TDateTime;
  134. begin
  135.   Result := SysUtils.Now;
  136. end;
  137.  
  138. function TTimeKeeper.GetTime: TDateTime;
  139. begin
  140.   Result := SysUtils.Time;
  141. end;
  142.  
  143. // Simplified functional interface
  144.  
  145. function TimeKeeper: TTimeKeeper;
  146. begin
  147.   Result := TTimeKeeper.Instance;
  148. end;
  149.  
  150. initialization
  151. finalization
  152. // Destroy when application closes
  153.   TTimeKeeper.Shutdown;
  154. end.
  155.